package org.paul.noconfig.vm

import android.content.Intent
import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.switchMap
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.delay
import org.paul.ConfigAdapter
import org.paul.R
import java.io.File
import java.io.Serializable
import java.util.*

class NoConfigViewModelActivity : AppCompatActivity() {
    private val viewModel: NoConfigViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_config_viewmodel)
        val content = findViewById<AppCompatTextView>(R.id.content)
        viewModel.data.observe(this, Observer {
            content.text = getString(R.string.time_fmt, it)
        })
        val adapter = ConfigAdapter()
        findViewById<RecyclerView>(R.id.recycler).apply {
            this.adapter = adapter
        }
        viewModel.generateList.observe(this, Observer {
            adapter.submitList(it)
        })
        val container = findViewById<ConstraintLayout>(R.id.container)
        if(resources.configuration.orientation== ORIENTATION_LANDSCAPE)
        {
            val intent = Intent().apply {
                val constraintSet = ConstraintSet().apply { clone(container) }
                putExtra("config",ConstraintSetExt(constraintSet))
            }
            setResult(0x0b,intent)
        }
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        if (newConfig.orientation != orientation) {
            // means config changed
            Log.d(tag, "NoConfigViewModelActivity config changed and now it is ${newConfig.orientation}")
            // load local contrainset

            // save new orientation

            if (newConfig.orientation == ORIENTATION_LANDSCAPE) {
                val constraintSet = ConstraintSet().apply { clone(baseContext, R.id.container) }
//                val file = File(baseContext.dataDir.path, "constraint/activity_config_viewmodel")
//                val createNewFile =
//                    file.createNewFile()
//                if (createNewFile){
//
//                }
                val intent = Intent().apply {
                    putExtra("config",ConstraintSetExt(constraintSet))
                }
                setResult(0x0b,intent)

            }

            orientation = newConfig.orientation
        }
    }

    private val tag = "configChange"
    var orientation: Int = ORIENTATION_PORTRAIT
}

class ConstraintSetExt(val set: ConstraintSet) :Serializable{
    init {
        set.
    }
}

class NoConfigViewModel : ViewModel() {

    private val _data: LiveData<String> = liveData {
        var i = 1
        while (true) {
            emit("${i++}")
            delay(1000)
        }
    }
    val data: LiveData<String> = _data

    private val _generateList = liveData<List<String>> {
        var i = 1
        val result = mutableListOf<String>()
        while (i < 100) {
            result.add("无配置带ViewModel的Activity[$i]")
            i++
        }
        emit(result)
    }
    val generateList: LiveData<List<String>> = _generateList

    // Exposed LiveData from a function that returns a LiveData generated with a liveData builder
    private val currentTime = liveData<Long> {
        while (true) {
            emit(System.currentTimeMillis())
            delay(1000)
        }
    }

    // Coroutines inside a transformation
    val currentTimeTransformed = currentTime.switchMap {
        // timeStampToTime is a suspend function so we need to call it from a coroutine.
        liveData { emit(timeStampToTime(it)) }
    }

    // Simulates a long-running computation in a background thread
    private suspend fun timeStampToTime(timestamp: Long): String {
        delay(500)  // Simulate long operation
        val date = Date(timestamp)
        return date.toString()
    }


}